/**
 * Bir adet TCP/IP bağlantı sağlamak istiyorsal bir adet sunucu ve 
 * bir adet istemci olması gerekiyor aşağıda tanımlayacağımız sınıf sunucu sınıfı olacaktır.
 * 
 * ----
 * TCP:|
 * ----
 *  Connection-oriented protocol: İki bilgisayar arasındaki veri iletiminin bütünlüğünü temin ediyor. Veri kaybı yok.
 *  Example : Http, Ftp 
 *  Bağlantı yolunu belirlemek için port numaralarını kullanıyor.
 * 
 * -----
 * Port:| 16 bit integer değer. 1024 kadar port numaraları rezerve edildiğinden dolayı. 1024 üstündeki 16 bit integer değerler port numarası olarak kullanılır.
 * -----
 * 
 * ---
 * IP:| İnternet ortamında bulunan bütün bilgisayarlar 4 byte uzunluğunda uniq bir değerle tanımlanırlar.  
 * ---
 * 
 * Bilgisayar vir adet IP adresi olmasına karşı birden çok bilgisayarla her biri birbirinden farklı olabilecek işlemler
 * bağlantılar gerçekleştirilir. Bu servisleri işlemleri birbirinden ayırmak için bilgisayar port mantığını kullanır.
 * Bu şu anlama geliyor herbir servis kendisi için uniq olan bir port numarası ile işlem yapar.
 * 
 * ----------------
 * Internet Paketi:| Gideceği bilgisayarın host adresini ve o bilgisayarla iletişim kuracağı port numarasına sahiptir.
 * ----------------
 * 
 * IP adresi bir apartmanın adresi gibiyken port numarasıda o apartmanda bulunan dairelerin numaralarıdır.
 * Kapıcı postayı teslim alır ve hangi daireye gidecekse teslim eder.
 * 
 * -------
 * Socket:| Programların networkte iletiminin nasıl sağlanacağı belirtmek için transport layerda için bir arayüzdür. 
 * -------
 * 
 * -------
 * Stream:| Soket verileri stream türünden nesnelerde tutar.
 * -------
 * */

package TCP_Server_Client;
/* The java.io package contains the basics needed for IO operations. */
import java.io.*;
/*  The java.net package contains the basics needed for network operations. */  
/*  The package containing various classes required for creating sockets and message communication using two different protocol UDP and TCP */
import java.net.*;

/**
 * 
 * @author necmeddin
 * @version 0.1.
 * 
 * Sunucu berlenen bir porttan dinleme yapar. İletişimi input ve output stream aracılığı ile yapar. 
 */
public class TCPServer {
    
   
    
    /**
     * Verilen integer bir sayının asal olup olmadığını sayının kareköküne kadar olan sayı kümesi
     * içinde kontrol edip geri true ve false boolean değerleri döndüren fonksiyon
     * 
     * @param number asal olup olmadığı bulunmak istenen integer sayı
     * @return boolean value sayı asal ise true değilse false dönen boolean değer
     */
    public static boolean isPrime(int number) 
    {
        if (number <  2) {return false;}
        
        if (number == 2) {return true;}
        
        // Çift sayıları test etmeyip, test kümesini küçültmek için bu şartı koyduk.
        if ((number % 2)== 0)   { return false;}
        
        for (int i = 3; i <= Math.sqrt(number)+1;i=i+2)
        {
            if((number%i) == 0) {   return false;   }
        }
        
        return true;
    }
    
    public static void main(String[] args) throws IOException, InterruptedException{
        
        String  serverName      =   "localhost";
        int     port            =   1234;
        
        
        try {
            
            InetAddress servername  =   InetAddress.getByName(serverName);
            
            //Server başlatılıyor. Ve porta bind ediliyor.
            System.out.println(Integer.toString(port)+" numaralı porttan dinleme yapacak bir server çalıştırılıyor....");
            ServerSocket server = new ServerSocket(port);   // 1234 nolu porttan dinleme yapıyor
            System.out.println("Server başlatıldı. "+server.getInetAddress()+ " adresinde "+server.getLocalPort()+" nolu porttan dinleme yapıyor.");
                
            // İstemci dinleyecek bir soket oluşturuluyor.
            System.out.println("İstemci istekleri dinleniyor...");
            Socket serverSoket = server.accept(); // soket istemciyle data transferini yapacağımız tünel.
            System.out.println("Sunucuya "+serverSoket.getInetAddress()+" adresi üzerinden "+serverSoket.getPort()+" numaralı portundan istemci bağlantısı oluşturuldu.");
            
            // İstemci data tarnsfer yapacak I/O streamlerini oluşturuyorum.
            DataInputStream     request     =   new DataInputStream(serverSoket.getInputStream());
            DataOutputStream    response    =   new DataOutputStream(serverSoket.getOutputStream());

            //Server Clienttan gelecek mesajı dinliyor...
            String receiveMessage = new String (request.readUTF());
            System.out.println(receiveMessage);

            //Sunucunun istemciye cevabı gönderiyor.
            response.writeUTF("Evet dostum buradayım gönder sayını, al cevabını. Soracakların bitince quit yaz yeter.");
         
            //Server Clienttan gelecek 2. mesajı dinliyor...
            receiveMessage = new String (request.readUTF());
            System.out.println("İstemciden  gelen mesaj içeriği : "+receiveMessage);

            while(receiveMessage.compareTo("quit") != 0)
            {           
                //Sunucunun istemciye 2. cevabı gönderiyor. 
                
                response.writeUTF(new Boolean(isPrime(Integer.parseInt(receiveMessage))).toString());
            
                //Server Clienttan gelecek 2. mesajı dinliyor...
                receiveMessage = new String (request.readUTF());
                System.out.println("İstemciden  gelen mesaj içeriği : "+receiveMessage);
            }
            
            response.close();
            request.close();
            System.out.println("Bu işte bitti, gelecek zaman bakalım neler gösterecek.");
            
        } catch (Exception e) {
            System.out.println("Bir şeyler oldu server çalışmadı hatada bu :"+e);
        }
        }
    }
